package com.pwt.service;

import com.pwt.common.ResultPage;
import com.pwt.entity.QWERTEVAR;
import com.pwt.model.*;
import com.pwt.model.crustallus.OrderModel;
import com.pwt.model.what.CharacteristicsModel;
import com.pwt.model.what.OverviewModel;
import com.pwt.repository.WERTEVARRepository;
import com.pwt.utils.DoubleUtils;
import com.pwt.utils.MathUtil;
import com.pwt.utils.SigmaUtil;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

/**
 * @author dw
 * @date 2021/11/15 15:39
 * @Description
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class LargeScreenService {

    WERTEVARRepository wertevarRepository;


    public LargeScreenService(WERTEVARRepository wertevarRepository) {
        this.wertevarRepository = wertevarRepository;
    }

    //总览数据
    public TotalDataModel getTotalData(){
        //当天
        Integer today = this.wertevarRepository.getTotalData(0);
        //昨天
        Integer yesterday = this.wertevarRepository.getTotalData(1);

        Integer add = today-yesterday;

        TotalDataModel dataModel = new TotalDataModel();
        dataModel.setToday(today);
        dataModel.setYesterday(yesterday);
        dataModel.setAdd(add);
        return dataModel;
    }

    //当天产品cp,cpk分布情况
    public List<DataModel> getTodayCpCpk(){

        //合格零件集合
        Set<String> ok = new HashSet<>();
        //不合格零件集合
        Set<String> noOk = new HashSet<>();
        //部分合格零件集合
        Set<String> someOk = new HashSet<>();

        List<String> part = this.wertevarRepository.queryWV0014ByDay(0);
        for(String k0014:part){
            List<OverviewModel> list = this.wertevarRepository.getPartCharacteristics(k0014);
            if(list == null || list.size() < 1) continue;
            for (OverviewModel over: list){
                //如果零件已经有参数是不合格或部分合格 那就不用在重复计算
                if(noOk.contains(k0014) || someOk.contains(k0014)){
                    ok.remove(k0014);
                    continue;
                } ;
                if(over.getK2110() == null || over.getK2111() == null) continue;
                List<Double> values = this.wertevarRepository.queryWERTEVARByDay(over.getK1000(),over.getK2000(),k0014);
                Double avg = SigmaUtil.avg(values);
                Double sigma = SigmaUtil.getSigma(values,avg);
                Double up = over.getK2111();
                Double down = over.getK2110();
                Double T = over.getK2111() - over.getK2110();
                //cp
                Double  cp= MathUtil.divDouble(T,6*sigma);
                cp = DoubleUtils.retain2(cp);
                Double cpu = MathUtil.divDouble((up - avg) , 3*sigma);
                cpu = DoubleUtils.retain2(cpu);
                Double cpl = MathUtil.divDouble((avg - down),3*sigma);
                cpl = DoubleUtils.retain2(cpl);
                //cpk
                Double cpk = Math.min(cpu,cpl);
                // 判断状态  产品是否合格
                if(cp >= over.getCpTarget()
                        && cpk >= over.getCpkTarget()){
                    if(values != null && values.size() <= 40 ){
                        someOk.add(k0014);
                    }else{
                        ok.add(k0014);
                    }
                }else{
                    noOk.add(k0014);
                }
            }

        }

        Integer total = ok.size()+noOk.size()+someOk.size();
        //返回集合
        List<DataModel> result = new ArrayList<>();
        if(total == null || total == 0){
            result.add(new DataModel("cp.cpk合格的产品",0.00));
            result.add(new DataModel("cp.cpk不合格的产品",0.00));
            result.add(new DataModel("cp.cpk部分合格的产品",0.00));
        }else{
            result.add(new DataModel("cp.cpk合格的产品", DoubleUtils.retainPercent2(Double.parseDouble(Integer.toString(ok.size()))/Double.parseDouble(total.toString()))));
            result.add(new DataModel("cp.cpk不合格的产品",DoubleUtils.retainPercent2(Double.parseDouble(Integer.toString(ok.size()))/Double.parseDouble(total.toString()))));
            result.add(new DataModel("cp.cpk部分合格的产品",DoubleUtils.retainPercent2(Double.parseDouble(Integer.toString(ok.size()))/Double.parseDouble(total.toString()))));
        }

        return result;
    }

    //事件返回
    public ResultPage<EventMeasuresModel> getEventMeasures(Integer page, Integer limit){
        ResultPage<EventMeasuresModel> list = this.wertevarRepository.getEventMeasures(page,limit);
        return list;
    }

    //工位生产情况
    public List<ProductionStationModel> productionStation(){
        return this.wertevarRepository.productionStation();
    }

    //近期产品cp,cpk分布情况
    public List<LargeDataModel>  partCpCpk(){
        //时间时间集合
        List<String> monthList = new LinkedList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.getTimeInMillis();
        monthList.add(dateFormat.format(calendar.getTime()));
        for (int i = 0; i < 6; i++) {
            calendar.add(Calendar.MONTH,-1);
            monthList.add(dateFormat.format(calendar.getTime()));
        }

        LargeDataModel dataModel1 = new LargeDataModel();
        dataModel1.setDateList(monthList);
        dataModel1.setName("合格的cp,cpk产品");
        dataModel1.setList(new ArrayList<Integer>());
        LargeDataModel dataModel2 = new LargeDataModel();
        dataModel2.setDateList(monthList);
        dataModel2.setName("不合格的cp,cpk产品");
        dataModel2.setList(new ArrayList<Integer>());
        LargeDataModel dataModel3 = new LargeDataModel();
        dataModel3.setDateList(monthList);
        dataModel3.setName("部分合格的cp,cpk产品");
        dataModel3.setList(new ArrayList<Integer>());
        for (String month:monthList){
            //合格零件集合
            Set<String> ok = new HashSet<>();
            //不合格零件集合
            Set<String> noOk = new HashSet<>();
            //部分合格零件集合
            Set<String> someOk = new HashSet<>();
            List<String> parts = this.wertevarRepository.queryWV0014ByMonth(month);
            if(parts == null || parts.size() < 1) continue;
            for (String k0014:parts){
                List<OverviewModel> list = this.wertevarRepository.getPartCharacteristics(k0014);
                if(list == null || list.size() < 1) continue;
                for (OverviewModel over: list){
                    //如果零件已经有参数是不合格或部分合格 那就不用在重复计算
                    if(noOk.contains(k0014) || someOk.contains(k0014)) {
                        ok.remove(k0014);
                        continue;
                    };
                    if(over.getK2110() == null || over.getK2111() == null) continue;
                    List<Double> values = this.wertevarRepository.queryWERTEVARByMonth(month,over.getK1000(),over.getK2000(),k0014);
                    Double avg = SigmaUtil.avg(values);
                    Double sigma = SigmaUtil.getSigma(values,avg);
                    Double up = over.getK2111();
                    Double down = over.getK2110();
                    Double T = over.getK2111() - over.getK2110();
                    //cp
                    Double  cp= MathUtil.divDouble(T,6*sigma);
                    cp = DoubleUtils.retain2(cp);
                    Double cpu = MathUtil.divDouble((up - avg),3*sigma);
                    cpu = DoubleUtils.retain2(cpu);
                    Double cpl = MathUtil.divDouble((avg - down) , 3*sigma);
                    cpl = DoubleUtils.retain2(cpl);
                    //cpk
                    Double cpk = Math.min(cpu,cpl);
                    // 判断状态  产品是否合格
                    if(cp >= over.getCpTarget()
                            && cpk >= over.getCpkTarget()){
                        if(values != null && values.size() <= 40 ){
                            someOk.add(k0014);
                        }else{
                            ok.add(k0014);
                        }
                    }else{
                        noOk.add(k0014);
                    }
                }
            }

            //合格
            dataModel1.getList().add(ok.size());
            //不合格
            dataModel2.getList().add(noOk.size());
            //部分合格
            dataModel3.getList().add(someOk.size());
        }
        List<LargeDataModel>  result = new ArrayList<>();
        result.add(dataModel1);
        result.add(dataModel2);
        result.add(dataModel3);
        return result;
    }


    //cp，cpk增长情况
    public List<LargeDataModel>  curveCpCpk(){
        //时间时间集合
        List<String> dayList = new LinkedList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Long datetime = System.currentTimeMillis();
        for (int i = 0; i < 15; i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date(datetime-i*1000*60*60*24));
            dayList.add(dateFormat.format(calendar.getTime()));
        }

        LargeDataModel dataModel1 = new LargeDataModel();
        dataModel1.setDateList(dayList);
        dataModel1.setName("合格的cp,cpk产品");
        dataModel1.setList(new ArrayList<Integer>());
        LargeDataModel dataModel2 = new LargeDataModel();
        dataModel2.setDateList(dayList);
        dataModel2.setName("不合格的cp,cpk产品");
        dataModel2.setList(new ArrayList<Integer>());
        LargeDataModel dataModel3 = new LargeDataModel();
        dataModel3.setDateList(dayList);
        dataModel3.setName("部分合格的cp,cpk产品");
        dataModel3.setList(new ArrayList<Integer>());
        for (String day:dayList){
            //合格零件集合
            Set<String> ok = new HashSet<>();
            //不合格零件集合
            Set<String> noOk = new HashSet<>();
            //部分合格零件集合
            Set<String> someOk = new HashSet<>();
            List<String> parts = this.wertevarRepository.queryWV0014ByDay(day);
            if(parts == null || parts.size() < 1) continue;
            for(String k0014 : parts){
                List<OverviewModel> list = this.wertevarRepository.getPartCharacteristics(k0014);
                for (OverviewModel over: list){
                    //如果零件已经有参数是不合格或部分合格 那就不用在重复计算
                    if(noOk.contains(k0014) || someOk.contains(k0014)) {
                        ok.remove(k0014);
                        continue;
                    };
                    if(over.getK2110() == null || over.getK2111() == null) continue;
                    List<Double> values = this.wertevarRepository.queryWERTEVARByDay(day,over.getK1000(),over.getK2000(),k0014);
                    Double avg = SigmaUtil.avg(values);
                    Double sigma = SigmaUtil.getSigma(values,avg);
                    Double up = over.getK2111();
                    Double down = over.getK2110();
                    Double T = over.getK2111() - over.getK2110();
                    //cp
                    Double  cp= MathUtil.divDouble(T,6*sigma);
                    cp = DoubleUtils.retain2(cp);
                    Double cpu = MathUtil.divDouble((up - avg) , 3*sigma);
                    cpu = DoubleUtils.retain2(cpu);
                    Double cpl = MathUtil.divDouble((avg - down) , 3*sigma);
                    cpl = DoubleUtils.retain2(cpl);
                    //cpk
                    Double cpk = Math.min(cpu,cpl);
                    // 判断状态  产品是否合格
                    if(cp >= over.getCpTarget()
                            && cpk >= over.getCpkTarget()){
                        if(values != null && values.size() <= 40 ){
                            someOk.add(k0014);
                        }else{
                            ok.add(k0014);
                        }
                    }else{
                        noOk.add(k0014);
                    }
                }
            }

            //合格
            dataModel1.getList().add(ok.size());
            //不合格
            dataModel2.getList().add(noOk.size());
            //部分合格
            dataModel3.getList().add(someOk.size());
        }
        List<LargeDataModel>  result = new ArrayList<>();
        result.add(dataModel1);
        result.add(dataModel2);
        result.add(dataModel3);
        return result;
    }


    public static void main(String[] args) {
        //时间时间集合
        List<String> monthList = new LinkedList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        for (int i = 1; i < 6; i++) {
            calendar.add(Calendar.MONTH,-1);
            monthList.add(dateFormat.format(calendar.getTime()));
        }
    }
}